package kubevirtsvc

import (
	"errors"
	"fmt"
	corev1 "gluenet/internal/agent/api/core/v1"
	"gluenet/internal/agent/driver/k8sdriver/data"
	"gluenet/internal/agent/driver/k8sdriver/option"
	"gluenet/internal/agent/driver/virtdriver/options"
)

func (svc *Service) CreateVirtualMachineService(vms *corev1.KubeVirtVirtualMachineService) (resp corev1.CommonResp) {
	if err := svc.createVirtualMachineService(vms); err != nil {
		svc.logger.Errorf(err.Error())
		resp = corev1.NewCommonFailureResp(err.Error())
	} else {
		resp = corev1.NewCommonSuccessRespWithData(vms)
	}

	return
}

func (svc *Service) createVirtualMachineService(vms *corev1.KubeVirtVirtualMachineService) error {
	if !svc.objects.IsExist(vms.GluenetGuid, `vm`) || !svc.objects.IsExist(vms.GluenetGuid, `vmi`) {
		return errors.New("run virtual machine first")
	}

	spec := vms.Spec

	if err := svc.vd.ExposeVMI(spec.VirtualMachineInstanceName, options.ExposeVmiOptions{
		Name:       spec.Name,
		NameSpace:  vms.GluenetGuid,
		Type:       spec.Type,
		Port:       spec.Port,
		TargetPort: spec.TargetPort,
	}); err != nil {
		return err
	}

	return svc.objects.Put(
		vms.GluenetGuid,
		vms.GluenetKind,
		&corev1.KubeVirtVirtualMachineServiceObj{
			GluenetMeta: vms.GluenetMeta,
			Spec:        vms.Spec,
			Status:      corev1.Status{State: corev1.StatusReady},
		})
}

func (svc *Service) GetVirtualMachineService(meta *corev1.GluenetMeta) corev1.CommonResp {
	var err error
	var k8sService *data.SimpleService

	obj, err := svc.objects.Get(meta.GluenetGuid, meta.GluenetKind)
	vms, ok := obj.(corev1.KubeVirtVirtualMachineServiceObj)

	if err != nil && !ok {
		goto ErrProcess
	}

	k8sService, err = svc.kd.GetService(vms.Spec.Name, option.GetServiceOptions{NameSpace: vms.GluenetGuid})
	if err != nil || k8sService.Spec.ClusterIP == `` {
		goto ErrProcess
	}

	vms.Spec.Entry = fmt.Sprintf("%s:%d", k8sService.Spec.ClusterIP, vms.Spec.Port)

	return corev1.NewCommonSuccessRespWithData(vms)

ErrProcess:
	svc.logger.Errorf(err.Error())
	return corev1.NewCommonFailureResp(err.Error())
}

func (svc *Service) DeleteVirtualMachineService(meta *corev1.GluenetMeta) corev1.CommonResp {
	var err error

	obj, err := svc.objects.Get(meta.GluenetGuid, meta.GluenetKind)
	vms, ok := obj.(*corev1.KubeVirtVirtualMachineServiceObj)

	if err != nil && !ok {
		goto ErrProcess
	} else {
		vms.Status.State = corev1.StatusTerminating
	}

	if err = svc.kd.DeleteService(vms.GluenetGuid, vms.Spec.Name); err != nil {
		goto ErrProcess
	} else {
		vms.Status.State = corev1.StatusTerminated
	}

	if err := svc.objects.Delete(meta.GluenetGuid, meta.GluenetKind); err != nil {
		goto ErrProcess
	}

	return corev1.NewCommonSuccessRespWithData(nil)

ErrProcess:
	vms.Status.State = corev1.StatusError
	svc.logger.Errorf(err.Error())
	return corev1.NewCommonFailureResp(err.Error())
}
